package com.spring.cloud.advice;


import com.alibaba.fastjson.JSONException;
import com.spring.cloud.enums.BusinessMessage;
import com.spring.cloud.enums.ErrorMsgEnum;
import com.spring.cloud.exception.BusinessException;
import com.spring.cloud.exception.ErrorApiResultHandler;
import com.spring.cloud.exception.ValidException;
import com.spring.cloud.vo.JsonResult;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;

/**
 * @author hd
 * @date 2019/3/31
 *
 * 自定义异常处理
 */
@Slf4j
@ControllerAdvice   //拦截所有controller
public class BasicExceptionHandler {
    /** 日志记录器 */
    private final static Logger logger = LoggerFactory.getLogger(BasicExceptionHandler.class);

    private final static String LOG_TIPS = "【Controller异常处理器】";

    /** 空指针异常日志标题 */
    private final static String NPE_LOG_TIPS = LOG_TIPS + "【空指针异常】: ";

    /** 普通异常日志标题 */
    private final static String NORMAL_LOG_TIPS = LOG_TIPS + "【其他异常】: ";

    @Resource
    private ErrorApiResultHandler errorApiResultHandler;
    private Map<String, BusinessMessage> businessMessageCodeMap;

    /**
     * 业务异常处理器
     * @param request HttpServletRequest
     * @param e Exception
     * @return ClientResult
     */
    @ExceptionHandler(BusinessException.class)
    public JsonResult businessExceptionHandler(HttpServletRequest request, BusinessException e) {
        return errorApiResultHandler.handlerError(e, e.getBusinessMessage());
    }

    @ExceptionHandler({ValidException.class})
    public JsonResult validExceptionHandler(HttpServletRequest request, final ValidException e) {
        BusinessMessage businessMessage = (BusinessMessage)this.businessMessageCodeMap.get(e.getValidMessage());
        return businessMessage != null ? this.errorApiResultHandler.handlerError(e, businessMessage) : this.errorApiResultHandler.handlerError(e, new BusinessMessage() {
            @Override
            public Integer getCode() {
                return -10000;
            }

            @Override
            public String getMsg() {
                return e.getValidMessage();
            }
        });
    }



    /**
     * 其他异常处理器
     * @param request HttpServletRequest
     * @param e Exception
     * @return ClientResult
     */
    @ExceptionHandler(Exception.class)
    public JsonResult defaultExceptionHandler(HttpServletRequest request, Exception e) {

        // 判断是否是空指针异常
        if (e instanceof NullPointerException) {
            logger.error(NPE_LOG_TIPS, e);
            ErrorMsgEnum.E1.setMsg("java.lang.NullPointerException:"+e.getMessage());
        } else {
            logger.error(NORMAL_LOG_TIPS, e);
            ErrorMsgEnum.E1.setMsg(e.getMessage());
        }
        return errorApiResultHandler.handlerError(e,ErrorMsgEnum.E1);
    }

    /**
     * 主要处理使用@RequestBody时错误的json引起的Exception
     * @return ClientResult
     */
    @ExceptionHandler({HttpMessageNotReadableException.class, JSONException.class})
    public JsonResult errorJsonBodyHandler(Exception e) {
        return errorApiResultHandler.handlerError(e, ErrorMsgEnum.E8);
    }

    /**
     * 处理请求方式错误引起的异常
     * @return
     */
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public JsonResult errorRequestMethod(Exception e) {
        return errorApiResultHandler.handlerError(e, ErrorMsgEnum.E5);
    }

}
